#ifndef INCOGNITO_DHASHBLOCKINGCLIENT_HH
#define INCOGNITO_DHASHBLOCKINGCLIENT_HH

#include <dhashclient.h>
#include "incognito.h"

/**
 * Klasa opakowująca dla klasy dhashclient. Zamienia wywołania bazujące
 * na callback'ach na zwykłe wywołania blokujące.
 */
class DhashBlockingClient {
	private:
		DhashBlockingClient() {};

	protected:
		dhashclient *m_client;
		
		// Wstawianie bloków
		//	Wywołanie zwrotne (ang. callback)
		void insert_cb(dhash_stat stat, ptr<insert_info> info);
		//	Informacja o tym czy się udało
		bool write_ok;

		// Odczyt bloków
		// 	Wywołanie zwrotne (ang. callback)
		void retrieve_cb(str *buf, dhash_stat stat, ptr<dhash_block> bl, vec<chordID> vc);
		//	Informacja o tym czy się udało
		bool read_ok;

		volatile bool cb_ok;
		void wait_for_cb();
	public:
		// Klasy wyjątków
		class DhashException {};
		class DhashInsertException: DhashException {};
		class DhashRetrieveException: DhashException {};

		
		// Konstruktor/destruktor
		DhashBlockingClient(str sockname):m_client(new dhashclient(sockname)) {}
		~DhashBlockingClient() {delete m_client;}

		// Wstawianie bloków
		// 	Wstawia blok, którego klucz jest równy hash(buf).
		bigint insert(const char *buf, size_t buflen) throw(DhashInsertException);
		//	Wstawia blok buf pod kluczem key, ustawia odpowiedni typ bloku.
		bigint insert(bigint key, const char *buf, size_t buflen, bool key_is_hash=true) throw(DhashInsertException);

		// Pobieranie bloków
		//	Pobiera blok, allokuje dla niego miejsce w pamięci, ustawia odpowiednio parametry buf i buflen
		str retrieve(bigint key, bool key_is_hash=true) throw(DhashRetrieveException);
		

};

#endif  /* INCOGNITO_DHASHBLOCKINGCLIENT_HH */
